/**
 * This class provides data for plotting of clustering algorithm KMeans
 */
package org.wmine.visualization.data;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.jfree.data.general.Dataset;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.wmine.core.ProjectManager;
import org.wmine.data.DataSet;
import org.wmine.data.InvalidCursorPositionException;
import org.wmine.data.TableResultSet;
import org.wmine.data.XMLDataReader;
import org.wmine.visualization.data.KMeansData.TupleData;
import org.xml.sax.SAXException;

/**
 * @author Rajeev Kumar Thakur
 *
 */
public class KMeansDataProvider extends AbstractChartDataProvider {

	private Document xmlDocument;
	private KMeansData kMeansData;
	ArrayList<String> listOfIndexRecordForCluster;
	DataSet dataset;
	TableResultSet resultSet;
	
	public KMeansDataProvider(String fileName) throws ParserConfigurationException, FileNotFoundException, SAXException, IOException {
		kMeansData = new KMeansData();
		listOfIndexRecordForCluster = new ArrayList<String>();
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder parser = factory.newDocumentBuilder();
		if(ProjectManager.getUniqueInstance().isProjectOpened()){
			//System.out.println("in kmeans data provider "+ fileName);
			xmlDocument = (Document) parser.parse(new StringBufferInputStream(ProjectManager.getUniqueInstance().readFile(fileName)));
			parseOutputData();			
		}
		//File f = new File(fileName);
		//xmlDocument = (Document) parser.parse(new File(fileName));
		//parseOutputData();	
	}

	private void parseOutputData() throws FileNotFoundException, ParserConfigurationException, SAXException, IOException  {
		 
		NodeList kMeansOp= xmlDocument.getElementsByTagName("kmeansop");
		int no = kMeansOp.getLength();
		for (int i = 0; i < no; i++) {
			Element element = (Element) kMeansOp.item(i);
			String dataFile = getElementFromXmlFile(element,"datafile");	
			kMeansData.setDataFile(dataFile);
			//System.out.println("in parse data :"+kMeansData.getDataFile());
			
			NodeList attrList = xmlDocument.getElementsByTagName("atributes");
			for (int j = 0; j < attrList.getLength(); j++) {
				Element elementA = (Element) attrList.item(j);
				int noOfAttr = Integer.parseInt(getElementFromXmlFile(elementA,"noofattributes"));
				kMeansData.setNoOfAttributes(noOfAttr);
			//	System.out.println("in parse data :"+kMeansData.getNoOfAttributes());
				
				NodeList attNameList =(NodeList) xmlDocument.getElementsByTagName("attributename");
				
				Element element1 = (Element) attNameList.item(0);
				String attr1 = element1.getFirstChild().getNodeValue();
				kMeansData.setAttribute1(attr1);
		//		System.out.println(kMeansData.getAttribute1());
				
				Element element2 = (Element) attNameList.item(1);
				String attr2 = element2.getFirstChild().getNodeValue();
				kMeansData.setAttribute2(attr2);
		//		System.out.println(kMeansData.getAttribute2());				
			}
			NodeList clusters = xmlDocument.getElementsByTagName("clusters");
			for (int j = 0; j < clusters.getLength(); j++) {
				Element elementA = (Element) clusters.item(j);
				int noOfClusters = Integer.parseInt(getElementFromXmlFile(elementA, "noofclusters"));
				kMeansData.setNoOfClusters(noOfClusters);
			//	System.out.println("in parsedata :"+kMeansData.getNoOfClusters());
				
				NodeList clusterList = (NodeList) xmlDocument.getElementsByTagName("cluster");
			//	System.out.println("no of clusters :"+clusterList.getLength());
				for (int k = 0; k < clusterList.getLength(); k++) {
					Element elementB = (Element) clusterList.item(k);
					listOfIndexRecordForCluster.add(elementB.getFirstChild().getNodeValue());					
				}
			//	System.out.println(listOfIndexRecordForCluster);				
			}
		}
			setTupleValuesForKMeans();
	}
	
	
	private void setTupleValuesForKMeans() throws FileNotFoundException, ParserConfigurationException, SAXException, IOException {
		// TODO Auto-generated method stub
		ArrayList<TupleData> tupleList = new ArrayList<TupleData>();
			
		dataset = new DataSet();	
		dataset.setDataReader(new XMLDataReader(new StringBufferInputStream(ProjectManager.getUniqueInstance().readFile(kMeansData.getDataFile()))));
		resultSet = dataset.getTableResultSet();
		for (int i = 0; i < listOfIndexRecordForCluster.size(); i++) {
			StringTokenizer dataTuple = new StringTokenizer(listOfIndexRecordForCluster.get(i),",");
			ArrayList<Double> xData = new ArrayList<Double>();
			ArrayList<Double> yData = new ArrayList<Double>();
		
			while(dataTuple.hasMoreTokens()){
				int tupleNo = Integer.parseInt(dataTuple.nextToken());
				// System.out.println("tuple ids :"+tupleNo);
				
			 while(resultSet.hasNext()){
				 try {
					if(Integer.parseInt(resultSet.getString(0)) == tupleNo){
						Double xDataItem, yDataItem;
						xDataItem = Double.parseDouble(resultSet.getString(kMeansData.getAttribute1()));
						xData.add(xDataItem);
						yDataItem = Double.parseDouble(resultSet.getString(kMeansData.getAttribute2()));
						yData.add(yDataItem);
					//	System.out.print("tuple values for "+i+" cluster "+xDataItem);
					//	System.out.println(" "+yDataItem);		
					}
				} catch (InvalidCursorPositionException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}							
			 }
			 resultSet.reset();
			}
			TupleData tupleData = kMeansData.getTupleDataInstance();
			tupleData.setXData(xData);
			tupleData.setYData(yData);
			tupleList.add(tupleData);	
			//System.out.print("tuple values :"+tupleData.getXData());
			//System.out.println(" "+tupleData.getYData());		
			
		}
		kMeansData.setClusterList(tupleList);
		
	//	ArrayList<TupleData> tempClusterList = new ArrayList<TupleData>();
	//	tempClusterList = kMeansData.getClusterList();
	//	for (int i = 0; i < tempClusterList.size(); i++) {
			//System.out.println("size of clusterlist "+tempClusterList.size());
	//		TupleData tempTuple = tempClusterList.get(i);
			//System.out.println("in clusterlist "+ i +" : Xdata "+tempTuple.getXData() +" Ydata : "+tempTuple.getYData());	
	//	}
		

	}

	public String getElementFromXmlFile(Element elementA, String tagName){
		NodeList temp = (NodeList) elementA.getElementsByTagName(tagName);
		Element subElement = (Element) temp.item(0);
			return subElement.getFirstChild().getNodeValue();
	}
	@Override
	
	public Object getChartData() {
		// TODO Auto-generated method stub
		return kMeansData;
	}
	
	
public static void main(String[] args) throws FileNotFoundException, ParserConfigurationException, SAXException, IOException {
	AbstractChartDataProvider data;
	data = new KMeansDataProvider("C:\\Documents and Settings\\Administrator\\My Documents\\NeetaS\\KmeansOp.xml");
}
}
